package net.lab1024.sa.admin.module.business.traffic.aibi.tcp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.traffic.aibi.service.AibiCameraProcessingService;
import net.lab1024.sa.admin.module.business.traffic.config.AibiCameraProperties;

/**
 * 艾比摄像机 TCP 客户端
 */
@Slf4j
@Component
public class AibiCameraTcpClient {

    @Resource
    private AibiCameraProperties cameraProperties;

    @Resource
    private AibiCameraProcessingService processingService;

    private volatile boolean running = false;
    private Thread workerThread;

    @PostConstruct
    public void start() {
        if (!cameraProperties.isEnabled()) {
            log.info("Aibi 摄像机 TCP 客户端未启用");
            return;
        }
        running = true;
        workerThread = new Thread(this::runLoop, "aibi-camera-tcp-client");
        workerThread.setDaemon(true);
        workerThread.start();
    }

    private void runLoop() {
        String host = cameraProperties.getTcp().getHost();
        int port = cameraProperties.getTcp().getPort();
        int reconnectDelay = Math.max(1, cameraProperties.getRetry().getReconnectDelaySeconds());

        while (running) {
            try (Socket socket = new Socket()) {
                socket.connect(new InetSocketAddress(host, port), cameraProperties.getTcp().getConnectTimeoutMillis());
                socket.setSoTimeout(cameraProperties.getTcp().getReadTimeoutMillis());
                socket.setKeepAlive(true);
                log.info("成功连接到艾比摄像机 TCP 服务 {}:{}", host, port);

                try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8))) {
                    String line;
                    while (running && (line = reader.readLine()) != null) {
                        String payload = line.trim();
                        if (payload.isEmpty()) {
                            continue;
                        }
                        processingService.handlePayload(payload);
                    }
                }

            } catch (IOException ex) {
                if (!running) {
                    break;
                }
                log.warn("艾比摄像机 TCP 连接异常: {}", ex.getMessage());
                sleepSeconds(cameraProperties.getRetry().getErrorBackoffSeconds());
            }
            if (!running) {
                break;
            }
            sleepSeconds(reconnectDelay);
        }
    }

    private void sleepSeconds(int seconds) {
        if (seconds <= 0) {
            return;
        }
        try {
            Thread.sleep(seconds * 1000L);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    @PreDestroy
    public void shutdown() {
        running = false;
        if (Objects.nonNull(workerThread)) {
            workerThread.interrupt();
        }
    }
}

